package com.slcf.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.slcf.common.Constant;
import com.slcf.dao.WxConfigMapper;

/**
 * @author zhangze
 */
@Component
@EnableScheduling
public class WeChatUtils {
	
	@Autowired
	private WxConfigMapper wxConfigMapper;
	
	// 公众号基础access_token
	private static String Request_Access_Token_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
			+ Constant.WX_APP_ID + "&secret=" + Constant.WX_APP_SECRET;
	// 签名票据
	private static String Request_Jsapi_Ticket_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=";

	/**
	 * 定时任务，每6000秒刷新一次微信基础Access_Token以及Jsapi_Ticket
	 */
	@Scheduled(fixedRate = 6000 * 1000)
	public void refreshJob() {
		System.out.println("schedule job: " + new Date());
		refreshAccessToken();
	}
	
	/**
	 * 刷新微信基础Access_Token以及Jsapi_Ticket
	 */
	public void refreshAccessToken() {
		// 1. 获取基础Access_Token
		String accessTokenResult = HttpUtil.sendGet(Request_Access_Token_URL);
		System.out.println(accessTokenResult);
		JSONObject accessTokenJson = JSONObject.parseObject(accessTokenResult);
		String accessToken = accessTokenJson.getString("access_token");
		if (StringUtils.isEmpty(accessToken)) {
			System.err.println("获取基础Access_Token失败:" + accessTokenResult);
		}
		// 2. 通过基础Access_Token获取Jsapi_Ticket
		String jsapiTicketResult = HttpUtil.sendGet(Request_Jsapi_Ticket_URL + accessToken);
		System.out.println(jsapiTicketResult);
		JSONObject jsapiTicketJson = JSONObject.parseObject(jsapiTicketResult);
		String jsapiTicket = jsapiTicketJson.getString("ticket");
		if (StringUtils.isEmpty(jsapiTicket)) {
			System.err.println("获取基础Jsapi_Ticket失败:" + jsapiTicketResult);
		}
		wxConfigMapper.updateWxConfig(Constant.WX_APP_ID, accessToken, jsapiTicket);
	}

	
	/**
	 * JS-SDK使用权限签名算法
	 * @param url
	 * @param jsapi_ticket 微信JS-SDK签名票据
	 * @return
	 */
    public Map<String, String> sign(String url, String jsapi_ticket) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String signature = "";

        // 注意这里参数名必须全部小写，且必须有序
        // 对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）后，使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串
        String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url;
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        return ret;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    // 生成签名的随机串
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    // 生成签名的时间戳
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

}
